package com.doeis.uwork.common;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

public class ImageUtils {

	private static int per = 3;
	private static float maxWidth = 90f*per;
	private static float maxHeight = 90f*per;
	private static int radius = 10*per;

	private static Map<Integer, List<MyBitmap>> mMap = new HashMap<Integer, List<MyBitmap>>();
	static {
		init1();
	}

	public static void init() {
		for (int i = 1; i < 10; i++) {
			ColumnRowCount mCRC = generateColumnRowCountByCount(i);
			MyBitmap bitmap = null;

			float perBitmapWidth = (maxWidth - MyBitmap.devide * 2 * mCRC.columns) / mCRC.columns;
			float topDownDelta = maxHeight - (mCRC.rows * (perBitmapWidth + MyBitmap.devide * 2));
			List<MyBitmap> mList = new LinkedList<ImageUtils.MyBitmap>();
			for (int row = 0; row < mCRC.rows; row++) {
				for (int column = 0; column < mCRC.columns; column++) {
					bitmap = new MyBitmap();
					if (i == 7) {
						// System.out.println("row=>" + row);
					}
					bitmap.y = 1 + topDownDelta / 2 + row * 2 + row * perBitmapWidth;
					bitmap.x = 1 + column * 2 + column * perBitmapWidth;
					bitmap.width = bitmap.height = perBitmapWidth;
					if (i == 7) {
						// System.out.println("bitmap=>" + bitmap);
					}
					mList.add(bitmap);
				}
			}
			mMap.put(i, mList);
		}
		modifyListWhenCountThree();
		modifyListWhenCountFive();
		modifyListWhenCountSeven();
		modifyListWhenCountEight();
	}
	
	public static void init1() {
		
		int biankuang = 10;
		for (int i = 1; i < 10; i++) {
			ColumnRowCount mCRC = generateColumnRowCountByCount(i);
			MyBitmap bitmap = null;
			
			if (mCRC.columns==3) {
				biankuang = 12;
			}else if(mCRC.columns==2) {
				biankuang = 10;
			}else {
				biankuang = 6;
			}
			float perBitmapWidth = (maxWidth - biankuang) / mCRC.columns;//小图的宽高
			float topDownDelta = maxHeight - (mCRC.rows * perBitmapWidth+biankuang);
			float topY = 0;
			List<MyBitmap> mList = new LinkedList<ImageUtils.MyBitmap>();
			for (int row = 0; row < mCRC.rows; row++) {
				if (mCRC.rows==2) {
					if (row == 1) {
						topY += 4;
					}else {
						topY += 3;
					}
				}else {
					topY += 3;
				}
				
				float topx = 0;
				for (int column = 0; column < mCRC.columns; column++) {
					
					if (mCRC.columns==2) {
						if (column == 1) {
							topx += 4;
						}else {
							topx += 3;
						}
					}else {
						topx += 3;
					}
					bitmap = new MyBitmap();
					if (i == 7) {
						// System.out.println("row=>" + row);
					}
					bitmap.y = topDownDelta/2 + topY + row * perBitmapWidth;
					bitmap.x = topx + column * perBitmapWidth;
					bitmap.width = bitmap.height = perBitmapWidth;
					if (i == 7) {
						// System.out.println("bitmap=>" + bitmap);
					}
					mList.add(bitmap);
				}
			}
			mMap.put(i, mList);
		}
		System.out.println(mMap);
		modifyListWhenCountThree();
		modifyListWhenCountFive();
		modifyListWhenCountSeven();
		modifyListWhenCountEight();
	}

	private static void modifyListWhenCountThree() {
		List<MyBitmap> mList1 = mMap.get(3);
		MyBitmap mBitmap1 = mList1.get(0);
		MyBitmap mBitmap2 = mList1.get(1);
		MyBitmap mDesBitmap = new MyBitmap();
		mDesBitmap.width = mBitmap1.width;
		mDesBitmap.height = mBitmap1.height;
		mDesBitmap.y = mBitmap1.y;
		mDesBitmap.x = (mBitmap1.x + mBitmap2.x) / 2;
		mList1.set(0, mDesBitmap);
		mList1.remove(1);
	}

	private static void modifyListWhenCountFive() {
		List<MyBitmap> mList1 = mMap.get(5);
		MyBitmap mBitmap1 = mList1.get(0);
		MyBitmap mBitmap2 = mList1.get(1);
		MyBitmap mBitmap3 = mList1.get(2);
		MyBitmap mDesBitmap = new MyBitmap();
		mDesBitmap.width = mBitmap1.width;
		mDesBitmap.height = mBitmap1.height;
		mDesBitmap.y = mBitmap1.y;
		mDesBitmap.x = (mBitmap1.x + mBitmap2.x) / 2;

		MyBitmap mDesBitmap2 = new MyBitmap();
		mDesBitmap2.width = mBitmap2.width;
		mDesBitmap2.height = mBitmap2.height;
		mDesBitmap2.y = mBitmap2.y;
		mDesBitmap2.x = (mBitmap2.x + mBitmap3.x) / 2;
		mList1.set(0, mDesBitmap);
		mList1.set(1, mDesBitmap2);
		mList1.remove(2);
	}

	private static void modifyListWhenCountSeven() {
		List<MyBitmap> mList1 = mMap.get(7);
		//System.out.println("[modifyListWhenCountSeven]" + mList1.size());
		//System.out.println("[modifyListWhenCountSeven]" + mBitmap1);
		mList1.remove(0);
		mList1.remove(1);
	}

	private static void modifyListWhenCountEight() {
		List<MyBitmap> mList1 = mMap.get(8);
		MyBitmap mBitmap1 = mList1.get(0);
		MyBitmap mBitmap2 = mList1.get(1);
		MyBitmap mBitmap3 = mList1.get(2);
		MyBitmap mDesBitmap = new MyBitmap();
		mDesBitmap.width = mBitmap1.width;
		mDesBitmap.height = mBitmap1.height;
		mDesBitmap.y = mBitmap1.y;
		mDesBitmap.x = (mBitmap1.x + mBitmap2.x) / 2;

		MyBitmap mDesBitmap2 = new MyBitmap();
		mDesBitmap2.width = mBitmap2.width;
		mDesBitmap2.height = mBitmap2.height;
		mDesBitmap2.y = mBitmap2.y;
		mDesBitmap2.x = (mBitmap2.x + mBitmap3.x) / 2;
		mList1.set(0, mDesBitmap);
		mList1.set(1, mDesBitmap2);
		mList1.remove(2);
	}

	private static ColumnRowCount generateColumnRowCountByCount(int count) {
		switch (count) {
		case 2:
			return new ColumnRowCount(1, 2, count);
		case 3:
		case 4:
			return new ColumnRowCount(2, 2, count);
		case 5:
		case 6:
			return new ColumnRowCount(2, 3, count);
		case 7:
		case 8:
		case 9:
			return new ColumnRowCount(3, 3, count);
		default:
			return new ColumnRowCount(1, 1, count);
		}
	}

	private static class ColumnRowCount {
		int rows;
		int columns;
		int count;

		public ColumnRowCount(int rows, int column, int count) {
			super();
			this.rows = rows;
			this.columns = column;
			this.count = count;
		}

		@Override
		public String toString() {
			return "ColumnRowCount [rows=" + rows + ", columns=" + columns + ", count=" + count + "]";
		}
	}

	private static class MyBitmap {
		float x;
		float y;
		float width;
		float height;
		static int devide = 1;
		int index = -1;

		@Override
		public String toString() {
			return "MyBitmap [x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + ", devide=" + devide
					+ ", index=" + index + "]";
		}
	}

	public static void drawArcWithAL(int x, int y, int width, int height, int startAngle, int arcAngle, Graphics2D g2) {

		double H = 10; // 箭头高度
		double L = 4; // 底边的一半
		int x3 = 0;
		int y3 = 0;
		int x4 = 0;
		int y4 = 0;

		int sx = 0;
		int sy = 0;
		int ex = 0;
		int ey = 0;

		if (arcAngle > 0) {
			sx = 0;
			sy = y + (int) (height * 0.95);
			ex = width / 2 + x - 1;
			ey = y + 1;
		} else {
			// 从向到下
			sx = width + x;
			sy = y + (int) (height * 0.95);
			ex = width / 2 + x - 1;
			ey = y + height + 1;
		}

		double awrad = Math.atan(L / H); // 箭头角度
		double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
		double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
		double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
		double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
		double y_3 = ey - arrXY_1[1];
		double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
		double y_4 = ey - arrXY_2[1];

		Double X3 = new Double(x_3);
		x3 = X3.intValue();
		Double Y3 = new Double(y_3);
		y3 = Y3.intValue();
		Double X4 = new Double(x_4);
		x4 = X4.intValue();
		Double Y4 = new Double(y_4);
		y4 = Y4.intValue();
		// 画线
		g2.drawArc(x, y, width, height, startAngle, arcAngle);
		//
		GeneralPath triangle = new GeneralPath();
		triangle.moveTo(ex, ey);
		triangle.lineTo(x3, y3);
		triangle.lineTo(x4, y4);
		triangle.closePath();
		// 实心箭头
		g2.fill(triangle);
		// 非实心箭头
		// g2.draw(triangle);

	}

	/**
	 * 合并图片成九宫格
	 * 
	 * @param pics
	 * @param type
	 * @param dst_pic
	 * @author wxy
	 */
	public static void merge(String pics[],String type, String dst_pic) {
		int len = pics.length;
		if (len < 1) {
			System.out.println("pics 的长度小于1");
			return;
		}

		if (type.equals("file")) {
			File files[] = new File[len];
			for (int i = 0; i < pics.length; i++) {
				files[i] = new File(pics[i]);
			}
			merge(files, dst_pic);
		}else if (type.equals("url")) {
			URL urls[] = new URL[len];
			for (int i = 0; i < pics.length; i++) {
				try {
					urls[i] = new URL(pics[i]);
				} catch (MalformedURLException e) {
					e.printStackTrace();
				}
			}
			merge(urls, dst_pic);
		}
	}

	/**
	 * 
	 * @author wxy
	 * @param files
	 * @param type
	 * @param dst_pic
	 * @author wxy
	 */
	public static void merge(File files[], String dst_pic) {
		try {
			int len = files.length;
			List<MyBitmap> mList = mMap.get(len);
			BufferedImage[] imgs = new BufferedImage[files.length];
			for (int i = 0; i < files.length; i++) {
				MyBitmap myBitmap = mList.get(i);
				imgs[i] = resize((int) myBitmap.width, (int) myBitmap.height, files[i]);
				imgs[i] = makeRoundedCorner(imgs[i], radius);
			}
			int width = imgs[0].getWidth();
			int height = imgs[0].getHeight();
			int[] imgArray = new int[width * height];
			BufferedImage imgNew = new BufferedImage((int) maxWidth, (int) maxHeight, BufferedImage.TYPE_INT_ARGB);
			for (int i = 0; i < imgs.length; i++) {
				MyBitmap myBitmap = mList.get(i);
				imgs[i].getRGB(0, 0, width, height, imgArray, 0, width);
				imgNew.setRGB((int) myBitmap.x, (int) myBitmap.y, width, height, imgArray, 0, width);
			}
			File outFile = new File(dst_pic);
			ImageIO.write(imgNew, "png", outFile);// 写图片
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void merge(URL files[], String dst_pic) {
		try {
			int len = files.length;
			List<MyBitmap> mList = mMap.get(len);
			BufferedImage[] imgs = new BufferedImage[files.length];
			for (int i = 0; i < files.length; i++) {
				MyBitmap myBitmap = mList.get(i);
				imgs[i] = resize((int) myBitmap.width, (int) myBitmap.height, files[i]);
				imgs[i] = makeRoundedCorner(imgs[i], radius);
			}
			int width = imgs[0].getWidth();
			int height = imgs[0].getHeight();
			int[] imgArray = new int[width * height];
			BufferedImage imgNew = new BufferedImage((int) maxWidth, (int) maxHeight, BufferedImage.TYPE_INT_ARGB);
			for (int i = 0; i < imgs.length; i++) {
				MyBitmap myBitmap = mList.get(i);
				imgs[i].getRGB(0, 0, width, height, imgArray, 0, width);
				imgNew.setRGB((int) myBitmap.x, (int) myBitmap.y, width, height, imgArray, 0, width);
			}
			File outFile = new File(dst_pic);
			ImageIO.write(imgNew, "png", outFile);// 写图片
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2) {

		double H = 10; // 箭头高度
		double L = 4; // 底边的一半
		int x3 = 0;
		int y3 = 0;
		int x4 = 0;
		int y4 = 0;
		double awrad = Math.atan(L / H); // 箭头角度
		double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
		double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
		double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
		double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
		double y_3 = ey - arrXY_1[1];
		double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
		double y_4 = ey - arrXY_2[1];

		Double X3 = new Double(x_3);
		x3 = X3.intValue();
		Double Y3 = new Double(y_3);
		y3 = Y3.intValue();
		Double X4 = new Double(x_4);
		x4 = X4.intValue();
		Double Y4 = new Double(y_4);
		y4 = Y4.intValue();
		// 画线
		g2.drawLine(sx, sy, ex, ey);
		//
		GeneralPath triangle = new GeneralPath();
		triangle.moveTo(ex, ey);
		triangle.lineTo(x3, y3);
		triangle.lineTo(x4, y4);
		triangle.closePath();
		// 实心箭头
		g2.fill(triangle);
		// 非实心箭头
		// g2.draw(triangle);

	}

	// 计算
	public static double[] rotateVec(int px, int py, double ang, boolean isChLen, double newLen) {

		double mathstr[] = new double[2];
		// 矢量旋转函数，参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
		double vx = px * Math.cos(ang) - py * Math.sin(ang);
		double vy = px * Math.sin(ang) + py * Math.cos(ang);
		if (isChLen) {
			double d = Math.sqrt(vx * vx + vy * vy);
			vx = vx / d * newLen;
			vy = vy / d * newLen;
			mathstr[0] = vx;
			mathstr[1] = vy;
		}
		return mathstr;
	}

	/**
	 * 
	 * @param originalFile
	 *            原照片
	 * @param newWidth
	 * @throws IOException
	 * @author wxy 2015年4月30日星期四中国标准时间下午2:53:25
	 * 性能较慢
	 * @return
	 */
	public static BufferedImage resize(File originalFile, int newWidth) throws IOException {

		ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
		Image i = ii.getImage();
		Image resizedImage = null;

		int iWidth = i.getWidth(null);
		int iHeight = i.getHeight(null);

		if (iWidth > iHeight) {
			resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
		} else {
			resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
		}

		// This code ensures that all the pixels in the image are loaded.
		Image temp = new ImageIcon(resizedImage).getImage();

		// Create the buffered image.
		BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
				BufferedImage.TYPE_INT_RGB);

		// Copy image to buffered image.
		Graphics g = bufferedImage.createGraphics();

		// Clear background and paint the image.
		g.setColor(Color.white);
		g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
		g.drawImage(temp, 0, 0, null);
		g.dispose();

		// Soften.
		float softenFactor = 0.05f;
		float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0,
				softenFactor, 0 };
		Kernel kernel = new Kernel(3, 3, softenArray);
		ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
		bufferedImage = cOp.filter(bufferedImage, null);
		return bufferedImage;
	}


	public static BufferedImage resize(int newWidth, int newHeight, URL url) {
		try {
			BufferedImage imgsrc = ImageIO.read(url);
			BufferedImage newBufImg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
			newBufImg.getGraphics().drawImage(imgsrc.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0,null);
			return newBufImg;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	public static BufferedImage getBufferedImage(URL url){
		try {
			return  ImageIO.read(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static int getHeight(BufferedImage img,int width,boolean isWidth){
		int height = 0;
		if (img!=null) {
			int ogr_height = img.getHeight();
			int ogr_width = img.getWidth();
			if (isWidth) {
				height = width*ogr_height/ogr_width;
			}else {
				height = width*ogr_width/ogr_height;
			}
		}
		return height;
	}

	public static BufferedImage resize(int newWidth, int newHeight, String imgsrc) throws IOException {
		return resize(newWidth, newHeight, new File(imgsrc));
	}

	public static BufferedImage resize(int width, int height, File targetFile) throws IOException {
		Image image = ImageIO.read(targetFile);
		return resize(width, width, image);
	}

	public static BufferedImage resize(int width, int height, Image targetImage) {
		width = Math.max(width, 1);
		height = Math.max(height, 1);
		BufferedImage image = null;
		try {
			image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			image.getGraphics().drawImage(targetImage, 0, 0, width, height, null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return image;
	}
	/**
	 * 转换Image数据为byte数组
	 * @param image
	 *            Image对象
	 * @param format
	 *            image格式字符串.如"gif","png"
	 * @return byte数组
	 */
	public static byte[] imageToBytes(Image image, String format) {
		BufferedImage bImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
		Graphics bg = bImage.getGraphics();
		bg.drawImage(image, 0, 0, null);
		bg.dispose();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			ImageIO.write(bImage, format, out);
		} catch (IOException e) {
		e.printStackTrace();
		}
		return out.toByteArray();
	}

	/**
	 * 得到圆角
	 * @param image
	 * @param cornerRadius
	 * @return
	 * @author wxy 2015年4月30日星期四中国标准时间下午3:17:31
	 */
	public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius) {
		
		int w = image.getWidth();
		int h = image.getHeight();
		BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

		Graphics2D g2 = output.createGraphics();

		g2.setComposite(AlphaComposite.Src);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setColor(Color.WHITE);
		g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius));

		g2.setComposite(AlphaComposite.SrcAtop);
		g2.drawImage(image, 0, 0, null);

		g2.dispose();

		return output;
	}

	public static void main(String[] args) throws IOException {
		File file = new File("D:\\IMAGE");
		if (file.isDirectory()) {
			File files[] = file.listFiles();

			merge(files, "D:\\1.jpg");
		}
		
//		String files[] = {"http://ww2.sinaimg.cn/bmiddle/6cd6d028jw1ernqy0krzvj20fg0ckt9d.jpg","http://ww3.sinaimg.cn/bmiddle/61b69811gw1ernqx3w5l5j20c80czgmu.jpg","http://ww4.sinaimg.cn/bmiddle/c2326032jw1erhkj8mhtrj20c80c8dg9.jpg"};
//		merge(files,"url", "D:\\13.jpg");
		//writeImg("D:\\12.jpg", resize(500, 500, "D:\\1.jpg"), 1);
		
		/*File originalImage = new File("D:\\4.jpg");
		BufferedImage image = null;
		long start = System.currentTimeMillis();
		for (int i = 0; i < 1000; i++) {
			image = resize(originalImage, 50);
//			image = resize(150, 150, originalImage);
//			image = resize(150, 150, "D:\\4.jpg");
			writeImg("D:\\1.jpg", image, 1f);
		}
		long end = System.currentTimeMillis();
		System.out.println("花费了"+(end-start)+"ms");*/
	}
}
